package com.controller;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bean.Goods;
import com.bean.Msg;
import com.bean.Seckill;
import com.dao.SeckillMapper;
import com.service.impl.GoodsServiceImpl;
import com.service.impl.SeckillServiceImpl;
import org.apache.logging.log4j.util.Strings;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * 用于后台管理系统的controller4
 * 后台管理系统包括且不限于
 * 对商品表、用户表、订单表的分页展示、修改添加删除等操作
 * 发布秒杀活动
 * @author shkstart
 * @create 2022-06-16-8:31
 */
@RestController
@RequestMapping("/manage")
public class GoodsManageController {

    @Resource
    GoodsServiceImpl goodsService;

    @Resource
    SeckillServiceImpl seckillService;

    @Resource
    SeckillMapper seckillMapper;

    //对商品表的操作

    //更改旧商品或保存新的商品
    @PostMapping("/saveGoods")
    public Integer saveOrUpdateGoods(@RequestBody Goods goods){
        return goodsService.saveOrUpdateGoods(goods);
    }

    //根据id删除指定商品
    @DeleteMapping("/deleteGoods/{id}")
    public Integer deleteUser(@PathVariable Integer id){
        int i = goodsService.deleteGoodsById(id);
        return i;
    }

    //实现对商品的批量删除
    @PostMapping("/delGoods/batch")
    public boolean delGoodsBatch(@RequestBody List<Integer> ids){
        return goodsService.removeByIds(ids);
    }

    //    @GetMapping("/page")
//    public Map<String,Object> findPage(@RequestParam Integer pageNum,
//                                       @RequestParam Integer pageSize,
//                                       @RequestParam String userName){
//        pageNum=(pageNum-1)*pageSize;
//        List<User> users = userMapper.selectPage(pageNum, pageSize,userName);
//        Integer total = userMapper.selectTotal(userName);
//        Map<String,Object> res=new HashMap<>();
//        res.put("data",users);
//        res.put("total",total);
//        return  res;
//    }
    //分页+模糊查找商品

    @GetMapping("/goodsPage")
    public IPage<Goods> goodsPage(@RequestParam Integer pageNum,
                                  @RequestParam Integer pageSize,
                                  @RequestParam(defaultValue = "") String goodsName,//前端不传该参数时 默认为""
                                  @RequestParam(defaultValue = "") String goodsDisc){
        IPage<Goods> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();
        //当数据库中该数据为null也要模糊匹配查询
        queryWrapper.like(!Strings.isEmpty(goodsName),"goods_name",goodsName);
        queryWrapper.like(!Strings.isEmpty(goodsDisc),"goods_disc",goodsDisc);
        //        根据id倒叙排列
        queryWrapper.orderByDesc("goods_id");
        IPage<Goods> goodsPage = goodsService.page(page, queryWrapper);
        return goodsPage;
    }

    /**
     * 导出接口excel
     */
    @GetMapping("/exportGoods")
    public void export(HttpServletResponse response) throws IOException {
        //从数据库中导出所有数据
        List<Goods> list=goodsService.list();

        //在内存中操作 写出到浏览器
        ExcelWriter writer= ExcelUtil.getWriter(true);

        //自定义标题名 将实体类中的字段名和别名对应
        //在实体类中写了别名 controller中就不用了 不然会报错
//        writer.addHeaderAlias("goodsId", "商品编号");
//        writer.addHeaderAlias("goodsName", "商品名字");
//        writer.addHeaderAlias("goodsPrice", "商品价格");
//        writer.addHeaderAlias("goodsDisc", "商品描述");
//        writer.addHeaderAlias("goodsStock", "商品库存数");
//        writer.addHeaderAlias("goodsPic", "商品图片地址");
//        writer.addHeaderAlias("isSeckill", "是否参与秒杀（0不参与1参与）");
//        writer.addHeaderAlias("createTime", "创建时间");
//        writer.addHeaderAlias("updateTime", "最近更新时间");

        // 一次性写出list内的对象到excel，使用默认样式，强制输出标题
        writer.write(list, true);

        // 设置浏览器响应的格式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("商品后台信息", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        out.close();
        writer.close();
    }

    /**
     * 导入文件接口
     */
    @PostMapping("/importGoods")
    public void impGoods(MultipartFile file)throws Exception{
        InputStream inputStream = file.getInputStream();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        List<Goods> goods = reader.readAll(Goods.class);
        System.out.println(goods);
        goodsService.saveBatch(goods);
    }

    /**
     * 指定商品的秒杀活动开启
     */
    @GetMapping("/secKillOpen")
    public Msg secKillOpen(@RequestParam Integer goodsId,
                           @RequestParam(required = false) String startTime,
                           @RequestParam(required = false) String endTime) throws ParseException {

        //首先要保证只能有一件商品处于秒杀活动中
        //找出共开启了多少个秒杀活动
        QueryWrapper<Goods> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("is_seckill",1);
        int count = goodsService.count(queryWrapper1);
        //判断这个开启活动的商品是否和要修改的一致
        Goods one = goodsService.getOne(queryWrapper1);
        if(count!=0&&(one.getGoodsId()!=goodsId)) {
            return Msg.fail();
        }


        //根据id获取到 我们要进行秒杀活动的商品
        Goods good = goodsService.getById(goodsId);

        //将前端传入的字符串转换成data日期类型
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date start = sdf.parse(startTime);
        Date end = sdf.parse(endTime);
//        if(good.getIsSeckill()==1){
//            //如果 该商品已经处于活动中 则只需要修改秒杀表中的结束时间和开始
//            seckillMapper.updateSeckill_goods(goodsId,start,end);
//            return  Msg.success().add("goodsName",good.getGoodsName());
//        }

        //将其秒杀状态置为1(处于秒杀活动状态)
        good.setIsSeckill(1);
        goodsService.
updateGoods(good);
        //在秒杀表中查找秒杀表中是否已经含有了该商品的秒杀活动记录
        Seckill seckill = seckillMapper.getSeckill(good.getGoodsName());

        //如果没有找到了则就重新插入新纪录
        if(seckill==null){
            //在秒杀表中添加秒杀开启和结束的时间
            seckill = new Seckill(start, end);
            seckillMapper.insert(seckill);
            //获取自增的秒杀表主键id 并连接商品表中要参加活动的商品id和秒杀表对应的id
            Integer integer = seckillMapper.addSeckill_goods(good.getGoodsId(), seckill.getSeckillId());
        }else{
            //找到了 则在原有的记录中修改即可(保证在秒杀表中一件商品对应一条记录)
            seckillMapper.updateById(new Seckill(seckill.getSeckillId(),start,end,seckill.getCreateTime()));
        }

        return  Msg.success().add("goodsName",good.getGoodsName());
    }


    /**
     * 指定商品的秒杀活动关闭
     */
    @GetMapping("/secKillClose")
    public Msg secKillClose(@RequestParam Integer goodsId){
        Goods good = goodsService.getById(goodsId);
        good.setIsSeckill(0);
        goodsService.updateGoods(good);
        return Msg.success().add("goodsName",good.getGoodsName());
    }

    /**
     * 用于前端回显出当前商品的秒杀活动 开启和结束时间
     */
    @GetMapping("/getSeckillTime")
    public Seckill getSeckillTime(@RequestParam Integer goodsId){
        Goods good = goodsService.getById(goodsId);
        Seckill seckill = seckillMapper.getSeckill(good.getGoodsName());
        if(seckill!=null){
            return seckill;
        }
        return null;
    }
}
